package com.jim.director.framework.validation;

/**
 * 注解校验异常
 * 当注解校验失败时抛出此异常
 *
 * @author Jim
 * @date 2024/10/5
 */
public class AnnotationValidationException extends RuntimeException {

    private ValidationReport validationReport;

    public AnnotationValidationException(String message) {
        super(message);
    }

    public AnnotationValidationException(String message, Throwable cause) {
        super(message, cause);
    }

    public AnnotationValidationException(String message, ValidationReport report) {
        super(message);
        this.validationReport = report;
    }

    public AnnotationValidationException(ValidationReport report) {
        super("注解校验失败，发现 " + report.getErrorCount() + " 个错误");
        this.validationReport = report;
    }

    /**
     * 获取详细的校验报告
     * @return 校验报告，如果没有则返回null
     */
    public ValidationReport getValidationReport() {
        return validationReport;
    }

    /**
     * 获取包含校验报告的详细错误信息
     */
    @Override
    public String getMessage() {
        String baseMessage = super.getMessage();

        if (validationReport != null) {
            return baseMessage + "\n" + validationReport.generateReport();
        }

        return baseMessage;
    }

    /**
     * 创建一个带有详细错误信息的异常
     * @param report 校验报告
     * @return 格式化的异常实例
     */
    public static AnnotationValidationException withDetailedMessage(ValidationReport report) {
        StringBuilder message = new StringBuilder();
        message.append("Director框架注解校验失败!\n");
        message.append("发现 ").append(report.getErrorCount()).append(" 个错误");

        if (report.hasWarnings()) {
            message.append("，").append(report.getWarningCount()).append(" 个警告");
        }

        message.append("。\n\n详细信息:\n");

        // 添加主要错误信息
        if (!report.getAllErrors().isEmpty()) {
            message.append("错误:\n");
            for (String error : report.getAllErrors()) {
                message.append("  ❌ ").append(error).append("\n");
            }
        }

        return new AnnotationValidationException(message.toString(), report);
    }
}

